package com.pz.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.pz.gulimall.common.constant.ProductConstant;
import com.pz.gulimall.common.utils.PageUtils;
import com.pz.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.pz.gulimall.product.dao.AttrGroupDao;
import com.pz.gulimall.product.dao.CategoryDao;
import com.pz.gulimall.product.entity.*;
import com.pz.gulimall.product.service.ProductAttrValueService;
import com.pz.gulimall.product.vo.req.AttrGroupRelationReqVo;
import com.pz.gulimall.product.vo.req.AttrReqVo;
import com.pz.gulimall.product.vo.res.AttrResVo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pz.gulimall.common.utils.Query;

import com.pz.gulimall.product.dao.AttrDao;
import com.pz.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Resource
    private AttrAttrgroupRelationDao attrgroupRelationDao;

    @Resource
    private AttrGroupDao attrGroupDao;

    @Resource
    private CategoryDao categoryDao;
    @Resource
    private CategoryServiceImpl categoryService;
    @Autowired
    private ProductAttrValueService attrValueService;

    @Override
    public PageUtils queryPage(Map<String,Object> params, Long catId, String attrType) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        queryWrapper.eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_SALE.getMsg().equals(attrType) ? 0:1);
        if(catId != 0){
            queryWrapper.eq("catelog_id", catId);
        }
        if(key != null && !StringUtils.isEmpty(key)){
            queryWrapper.and((wapper)->{
                wapper.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();

        List<AttrResVo> attrResVoList = records.stream().map((attrEntity -> {
            AttrResVo attrResVo = new AttrResVo();
            try {
                BeanUtils.copyProperties(attrResVo, attrEntity);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            //为基础属性时，才有分组信息
            if(attrType.equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getMsg())){
                AttrAttrgroupRelationEntity attrAttrGroup = attrgroupRelationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq("attr_id",attrResVo.getAttrId()));
                if(attrAttrGroup != null){
                    //设置分组
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrAttrGroup.getAttrGroupId());
                    attrResVo.setAttrGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            CategoryEntity category = categoryDao.selectById(attrEntity.getCatelogId());
            if(category != null){
                //设置分类
                attrResVo.setCatelogName(category.getName());
            }

            return attrResVo;
        })).collect(Collectors.toList());
        pageUtils.setList(attrResVoList);

        return pageUtils;
    }

    @Override
    public void saveAttr(AttrReqVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        try {
            //保存基本数据库数据
            BeanUtils.copyProperties(attrEntity, attr);
            this.save(attrEntity);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        //保存关联关系
        if(attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrgroupRelationDao.insert(relationEntity);
        }
    }

    @Override
    public AttrResVo getAttrById(Long attrId) {
        AttrEntity attrEntity = getById(attrId);
        AttrResVo attrResVo = new AttrResVo();
        try {
            BeanUtils.copyProperties(attrResVo, attrEntity);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        //设置分类信息
        Long catId = attrResVo.getCatelogId();
        CategoryEntity category = categoryDao.selectById(catId);
        if(category != null){
            attrResVo.setCatelogName(category.getName());
        }
        Long[] cateLogPath = categoryService.findCatelogIdPath(catId);
        attrResVo.setCatelogPath(cateLogPath);

        //设置分组信息
        if(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() == attrResVo.getAttrType()){
            AttrAttrgroupRelationEntity attrgroupRelation = attrgroupRelationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq("attr_id", attrEntity.getAttrId()));
            if(attrgroupRelation != null){
                attrResVo.setAttrGroupId(attrgroupRelation.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupRelation.getAttrGroupId());
                if(attrGroupEntity != null){
                    attrResVo.setAttrGroupName(attrGroupEntity.getAttrGroupName());
                }

            }
        }
        return attrResVo;
    }

    @Override
    public void updateAttr(AttrReqVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        try {
            BeanUtils.copyProperties(attrEntity, attr);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        this.updateById(attrEntity);


        if(attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //修改分组关联
            AttrAttrgroupRelationEntity attrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrgroupRelationEntity.setAttrId(attr.getAttrId());
            attrgroupRelationDao.update(attrgroupRelationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>()
                    .eq("attr_id", attrEntity.getAttrId()));

            //先判定 attr_attrgroup_relation 表中是否有 修改的 attr_id 对应的数据记录
            Long count = attrgroupRelationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq("attr_id", attrEntity.getAttrId()));
            if(count>0){
                //已经存在，更新操作
                attrgroupRelationDao.update(attrgroupRelationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>()
                        .eq("attr_id", attrEntity.getAttrId()));
            }else {
                //不存在，添加操作
                attrgroupRelationDao.insert(attrgroupRelationEntity);
            }
        }

    }

    /**
     * 根据分组ID 查找关联的所有基本属性
     * @param attrGroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {
        //查出 attrGroupId 所关联的所有 attrId
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrgroupRelationDao.selectList(
                new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId)
        );
        if(attrAttrgroupRelationEntities != null && attrAttrgroupRelationEntities.size() > 0){
            List<Long> attrIds = attrAttrgroupRelationEntities.stream()
                    .map((AttrAttrgroupRelationEntity::getAttrId)).collect(Collectors.toList());

            return this.listByIds(attrIds);
        }else {
            return null;
        }

    }

    @Override
    public void delRelation(AttrGroupRelationReqVo[] vos) {
        List<AttrAttrgroupRelationEntity> entities = Arrays.asList(vos).stream().map((item)->{
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            try {
                BeanUtils.copyProperties(relationEntity,item);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            return relationEntity;
        }).collect(Collectors.toList());
        // delete from pms_attr_attrgroup_relation where (attr_id=? and attr_group_id=?) or (attr_id=? and attr_group_id=?) or ...
        //只执行一次删除操作
        attrgroupRelationDao.delBatchRelation(entities);
    }

    /**
     *  获取当前分组没有关联的所有属性
     * @param params
     * @param attrGroupId
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrGroupId) {
        //1、当前分组只能关联自己所属的分类里面的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
        Long catelogId = attrGroupEntity.getCatelogId();

        //2、当前分组只能关联别的分组没有关联的属性
        // 过滤出 本分组下已经关联过的 attrId
        List<Long> existAttrId = attrgroupRelationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                ).stream().map((item)->{
                    return item.getAttrId();
        }).collect(Collectors.toList());


        QueryWrapper<AttrEntity> w = new QueryWrapper<AttrEntity>()
                .eq("catelog_id",catelogId).notIn("attr_id",existAttrId);

        String key = (String) params.get("key");
        if(key!=null && !key.isEmpty()){
            w.eq("attr_id", key).or().like("attr_name", key);
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                w
        );
        return new PageUtils(page);
    }

    @Override
    public List<ProductAttrValueEntity> getAttrValueByspuId(Long spuId) {
        if(spuId != null){
            return attrValueService.list(new QueryWrapper<ProductAttrValueEntity>()
                    .eq("spu_id", spuId));
        }
        return new ArrayList<>();
    }

    @Transactional
    @Override
    public void updateAttrValueBySpuId(List<ProductAttrValueEntity> entities, Long spuId) {
        if(entities!=null && spuId!=null && entities.size()>0){
            // 删除原有 spuid 关联的所有 product_attr_value
            attrValueService.remove(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));

            //将传递过来的数据添加
            List<ProductAttrValueEntity> attrValueEntities = entities.stream().map(item -> {
                 item.setSpuId(spuId);
                 return item;
            }).collect(Collectors.toList());
            attrValueService.saveBatch(attrValueEntities);
        }
    }


    /**
     * 在指定的所有属性中 搜出可以被检索的 属性id
     * @param attrIds
     * @return
     */
    @Override
    public List<Long> listSearchAttrs(List<Long> attrIds) {
        return baseMapper.selectSearchAttrIds(attrIds);
    }




}